/*
 * SHDL.c
 *
 * Created: 9/04/2012 5:45:10 PM
 *  Author: Richard
 */ 
#include "SHDL.h"

/*
 *
 * Description: Number of tasks for each Run state container time
 *              
 */
#define SHDL__nNoOf10msTasks	( sizeof(apf10msMain) / sizeof(apf10msMain[0]) )
#define SHDL__nNoOf1000msTasks	( sizeof(apf1000msMain) / sizeof(apf1000msMain[0]) )

/*
 *
 * Description: Invalid task number/ID
 *              
 */
#define SHDL__nInvalidTask		0u 

/*
 *
 * Function Prototypes
 *              
 */
void SHDL__vContainer10ms( void );
void SHDL__vContainer1000ms( void );

typedef struct  
{
	uint8 u8Timer;
	uint8 u8NumberOfTasks;
	uint8 u8CurrentTask;
} SHDL__tstContainerData;

typedef struct
{
	SHDL__tstContainerData st10ms;
	SHDL__tstContainerData st1000ms;
} SHDL__tstRunContainers;

static SHDL__tstRunContainers SHDL__stRunContainers;
static volatile bool SHDL__boTick1ms;

void SHDL_vInit( void )
{
	SHDL__stRunContainers.st10ms.u8Timer = 0;
	SHDL__stRunContainers.st10ms.u8NumberOfTasks = SHDL__nNoOf10msTasks;
	SHDL__stRunContainers.st10ms.u8CurrentTask = SHDL__nNoOf10msTasks;
	
	SHDL__stRunContainers.st1000ms.u8Timer = 0;
	SHDL__stRunContainers.st1000ms.u8NumberOfTasks = SHDL__nNoOf1000msTasks;
	SHDL__stRunContainers.st1000ms.u8CurrentTask = SHDL__nNoOf1000msTasks;
	
	SHDL__boTick1ms = false;
}

void SHDL_vMain( void )
{
	if( SHDL__boTick1ms == true )
	{
		CLOCK_vStopInterrupt();
		SHDL__boTick1ms = false;
		CLOCK_vRestartInterrupt();
		
		/* Add 1ms Tasks here */
		TIMER_vInterruptHook();
		
		/* Update 10ms Container time */
		SHDL__stRunContainers.st10ms.u8Timer++;
	}
	else
	{
		/* Run all other tasks. All tasks longer than 10ms are called from the 10ms Container */
		SHDL__vContainer10ms();
	}
}

void SHDL_vContainter1ms( void )
{
	SHDL__boTick1ms = true;
}

void SHDL__vContainer10ms( void )
{
	if( SHDL__stRunContainers.st10ms.u8CurrentTask != SHDL__nInvalidTask )
	{	
		if( SHDL__stRunContainers.st10ms.u8CurrentTask-- )
		{
			apf10msMain[SHDL__stRunContainers.st10ms.u8CurrentTask]();
		}
	}
	else
	{
		/* 10ms timer has expired */
		if( SHDL__stRunContainers.st10ms.u8Timer >= 10u )
		{
			SHDL__stRunContainers.st10ms.u8Timer -= 10u;
			SHDL__stRunContainers.st10ms.u8CurrentTask = SHDL__nNoOf10msTasks;
			SHDL__stRunContainers.st1000ms.u8Timer++;
		}
		else
		{
			/* Run the other containers */
			SHDL__vContainer1000ms();
		}
	}
}

void SHDL__vContainer1000ms( void )
{
	if( SHDL__stRunContainers.st1000ms.u8CurrentTask != SHDL__nInvalidTask )
	{
		if( SHDL__stRunContainers.st1000ms.u8CurrentTask-- )
		{
			apf1000msMain[SHDL__stRunContainers.st1000ms.u8CurrentTask]();
		}		
	}	
	else
	{
		if( SHDL__stRunContainers.st1000ms.u8Timer >= 100u )
		{
			SHDL__stRunContainers.st1000ms.u8Timer -= 100u;
			SHDL__stRunContainers.st1000ms.u8CurrentTask = SHDL__nNoOf1000msTasks;
			/* update next task counter here */
		}			
		else
		{
			/* Run idle tasks */
			TIMER_vBackgroundTask();
		}			
	}			
}	
